﻿#region CREDIT & LICENSE
/*******************************************
 * CREDIT: 
 * http://www.ROMPROS.com 
 * Tremendously helpful website, also would
 * like to give special thanks to:
 * 
 * Roverser - for the great effort on a c repository 
 * that most of this was ported from. http://code.google.com/p/rombot/
 * 
 * ROMeo - for the great amount of information shared
 * all across the rompros site. http://www.rompros.com/member.php?u=1901
 * 
 * 
 * LICENSE:
 *  
 * RomAPI is c# library is used to communicate directly with
 * the Runes Of Magic game client. 
 * 
 * Copyright (C) 2010  digitalxarts@gmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 *******************************************/
#endregion#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Magic;
using RomAPI.Objects;
using RomAPI.Offsets;
namespace RomAPI
{
    public class RomClient
    {
        #region playerAddress
		/// <summary>
		/// Player search pattern used to find the static pointer to the player base
		/// </summary>
        private static byte[] playerPattern = new byte[] { 0x8B, 0x07, 0x8B, 0x0D, 0xFF, 0xFF, 0xFF, 0xFF, 0x56, 0x50, 0xE8 };
		/// <summary>
		/// Player search mask used to filter the search pattern.
		/// </summary>
        private static string playerMask = "xxxx????xxx";
        #endregion
		/* Currently Not Working
        #region macroAddress
        private static byte[] macroPattern = new byte[] { 0x0F, 0x84, 0xFF, 0xFF, 0xFF, 0xFF, 0x38, 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0x8D, 0xB8 };
        private static string macroMask = "xx????xx????xx";
        #endregion
		*/
		/// <summary>
		/// World holds all the information that is part of 
		/// the players environment.
		/// </summary>
        public RomWorld World;
		/// <summary>
		/// Player is the reference to the actual player that
		/// </summary>
        public RomPlayer Player;
		/// <summary>
		/// Memory is the memory manipulate class that allows 
		/// us to read/write to the client.exe
		/// </summary>
        public BlackMagic Memory { get; set; }
        public RomClient(int process)
        {
            try
            {
				//Attach to the process
                Memory = new BlackMagic(process);
                //Player Structure Base Address
                uint PlayerBaseAddress = Memory.ReadUInt(Memory.ReadUInt(Memory.FindPattern(playerPattern, playerMask) + (uint)RomClientOffset.PLAYER));
                //Creating a new Player for this client (passing reference to the client).
                Player = new RomPlayer(this, PlayerBaseAddress + (uint)RomClientOffset.PLAYER_BASE);
				//Creating a new World for this client (passing reference to the client).
                World = new RomWorld(this);
				/*not working yet....coming soon.
				//macro base address
                uint MacroBaseAddress = Memory.ReadUInt(Memory.FindPattern(macroPattern, macroMask) + (uint)ClientOffset.MACRO);
				*/
            }
            catch (Exception ex)
            {
				/* 
				 * We failed to attach to the client.exe process. 
				 * Use the CanAttachToProcess to validate if this process
				 * can be attached. Or we need to see if the client is actually in game.
				 * we can't find the player pointer if we aren't in game.
				 */
                throw ex;
				//Console.WriteLine(ex.Message);
            }
        }
		/// <summary>
		/// This function is used to validate if we can attach to the client process
		/// </summary>
		/// <param name="process">process id</param>
		/// <returns>true/false if we can attach to process.</returns>
		public static bool CanAttachToProcess(int process)
		{
			bool isAttachable = false;
			try
			{
				BlackMagic magic = new BlackMagic(process);
				isAttachable = true;
				//add extended logic to see if game is player is in game, and not login screen
                magic.Close();
			}
			catch(Exception e)
			{
				isAttachable = false;
			}
			return isAttachable;
		}
		
    }
    
    

}
